﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DoNetToolKit.Patterns.Strategy
{
    /*********************************************************************************
     * 
     * 策略模式（Strategy）：
     * 策略模式定义了一系列的算法，并将每一个算法封装起来，而且使它们还可以相互替换。
     * 策略模式让算法的变化不会影响到使用算法的客户。
     * 
     * 优点：
 　　* 1.简化了单元测试，因为每个算法都有自己的类，可以通过自己的接口单独测试。
 　　* 2.避免程序中使用多重条件转移语句，使系统更灵活，并易于扩展。
     * 3.遵守大部分GRASP原则和常用设计原则，高内聚、低偶合。
　　 * 缺点：
 　　* 1.因为每个具体策略类都会产生一个新类，所以会增加系统需要维护的类的数量。
     * 2.在基本的策略模式中，选择所用具体实现的职责由客户端对象承担，并转给策略模式的Context对象。
     *  （这本身没有解除客户端需要选择判断的压力，而策略模式与简单工厂模式结合后，
     *   选择具体实现的职责也可以由Context来承担，这就最大化的减轻了客户端的压力。）
     *********************************************************************************/

    class StrategyMain
    {
        public static void StrategyTest()
        {
            ListEntry<Person> pList = new ListEntry<Person>();
            Person p1 = new Person() { Name = "bbb", Age = 30 };
            Person p2 = new Person() { Name = "aaa", Age = 20 };
            Person p3 = new Person() { Name = "ccc", Age = 10 };
            pList.Add(p1);
            pList.Add(p2);
            pList.Add(p3);
            // 排序前：
            Console.WriteLine("排序前");
            for (int i = 0; i < pList.Count; i++)
            {
                //Person p = pList.Get(i);
                Person p = pList[i];
                Console.WriteLine(p.Name + "," + p.Age);
            }

            //按名字排序
            StrategyCompare cName = new NameSort();
            pList.Sort(cName);
            Console.WriteLine("按名字排序");
            for (int i = 0; i < pList.Count; i++)
            {
                Person p = pList[i];
                Console.WriteLine(p.Name + "," + p.Age);
            }

            //按年龄排序
            StrategyCompare cAge = new AgeSort();
            pList.Sort(cAge);
            Console.WriteLine("按年龄排序");
            for (int i = 0; i < pList.Count; i++)
            {
                Person p = pList[i];
                Console.WriteLine(p.Name + "," + p.Age);
            }
        }
    }
}
